package com.ruoyi.system.service.impl;

import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.HashMap;
import java.util.ArrayList;
import java.util.Arrays;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.http.HttpUtils;
import com.ruoyi.system.domain.DroneMission;
import com.ruoyi.system.mapper.DroneMissionMapper;
import com.ruoyi.system.service.IDroneMissionService;
import com.ruoyi.system.service.ISatelliteWeatherService;

/**
 * 无人机任务Service业务层处理
 */
@Service
public class DroneMissionServiceImpl implements IDroneMissionService {

    @Value("${drone.service.url:http://localhost:5002}")
    private String droneServiceUrl;

    @Autowired
    private DroneMissionMapper droneMissionMapper;

    @Autowired
    private ISatelliteWeatherService satelliteWeatherService;

    @Override
    public boolean connectDrone() {
        try {
            String url = droneServiceUrl + "/drone/connect";
            String response = HttpUtils.sendPost(url, String.valueOf(new HashMap<String, String>()));
            JSONObject result = JSON.parseObject(response);
            return result.getBooleanValue("success");
        } catch (Exception e) {
            throw new RuntimeException("连接无人机服务失败: " + e.getMessage());
        }
    }

    @Override
    public boolean disconnectDrone() {
        try {
            String url = droneServiceUrl + "/drone/disconnect";
            String response = HttpUtils.sendPost(url, String.valueOf(new HashMap<String, String>()));
            JSONObject result = JSON.parseObject(response);
            return result.getBooleanValue("success");
        } catch (Exception e) {
            throw new RuntimeException("断开无人机连接失败: " + e.getMessage());
        }
    }

    @Override
    public String startMission(Map<String, Object> missionParams) {
        try {
            // 检查天气条件是否适合飞行
            String location = missionParams.get("field_location") != null ?
                    missionParams.get("field_location").toString() : "默认农田区域";

            Map<String, Object> weatherData = satelliteWeatherService.getRealTimeWeather(location);
            String disasterRisk = (String) weatherData.get("disasterRisk");

            if ("高风险".equals(disasterRisk)) {
                throw new RuntimeException("当前区域存在高风险自然灾害，不适合无人机飞行");
            }

            Double windSpeed = (Double) weatherData.get("windSpeed");
            if (windSpeed != null && windSpeed > 12) {
                throw new RuntimeException("当前风速(" + windSpeed + "m/s)过大，不适合无人机飞行");
            }

            Double rainfall = (Double) weatherData.get("rainfall");
            if (rainfall != null && rainfall > 20) {
                throw new RuntimeException("当前降雨量(" + rainfall + "mm)过大，不适合无人机飞行");
            }

            // 检查无人机服务连接
            String url = droneServiceUrl + "/drone/mission/start";
            String jsonParams = JSON.toJSONString(missionParams);
            String response = HttpUtils.sendPostJson(url, jsonParams);
            JSONObject result = JSON.parseObject(response);

            if (result.getBooleanValue("success")) {
                String missionId = result.getString("mission_id");

                // 保存任务记录到数据库
                DroneMission mission = new DroneMission();
                mission.setMissionId(missionId);
                mission.setMissionName("巡田任务-" + DateUtils.dateTimeNow("yyyyMMddHHmmss"));
                mission.setFieldArea(Double.parseDouble(missionParams.get("field_area").toString()));
                mission.setFlightHeight(Integer.parseInt(missionParams.get("flight_height").toString()));
                mission.setMonitoringDensity(missionParams.get("monitoring_density").toString());
                mission.setFieldLocation(location);
                mission.setStatus("running");
                mission.setStartTime(new Date());
                mission.setCreateTime(new Date());

                // 保存天气条件信息到备注中
                String weatherInfo = String.format("任务开始时的天气条件: 温度%.1f°C, 湿度%.1f%%, 风速%.1fm/s, 风险%s",
                        weatherData.get("temperature"),
                        weatherData.get("humidity"),
                        weatherData.get("windSpeed"),
                        disasterRisk);
                mission.setRemark(weatherInfo);

                droneMissionMapper.insertDroneMission(mission);

                return missionId;
            } else {
                throw new RuntimeException(result.getString("message"));
            }
        } catch (Exception e) {
            throw new RuntimeException("启动任务失败: " + e.getMessage());
        }
    }

    @Override
    public Map<String, Object> stopMission() {
        try {
            String url = droneServiceUrl + "/drone/mission/stop";
            String response = HttpUtils.sendPost(url, String.valueOf(new HashMap<String, String>()));
            JSONObject result = JSON.parseObject(response);

            if (result.getBooleanValue("success")) {
                Map<String, Object> report = result.getObject("report", Map.class);

                // 更新任务状态
                String missionId = (String) report.get("mission_id");
                DroneMission mission = droneMissionMapper.selectDroneMissionById(missionId);
                if (mission != null) {
                    mission.setStatus("completed");
                    mission.setEndTime(new Date());
                    mission.setUpdateTime(new Date());

                    // 更新统计信息
                    Map<String, Object> summary = (Map<String, Object>) report.get("summary");
                    if (summary != null) {
                        mission.setDetectionCount((Integer) summary.get("total_pest_detections"));

                        // 设置主要病虫害
                        List<Map<String, Object>> mainThreats = (List<Map<String, Object>>) summary.get("main_pest_threats");
                        if (mainThreats != null && !mainThreats.isEmpty()) {
                            mission.setMainPest(mainThreats.get(0).get("pest").toString());
                        }
                    }

                    // 获取任务结束时的天气信息并添加到报告中
                    if (mission.getFieldLocation() != null) {
                        Map<String, Object> endWeather = satelliteWeatherService.getRealTimeWeather(mission.getFieldLocation());
                        report.put("end_weather_conditions", endWeather);

                        // 更新备注，添加结束时的天气信息
                        String currentRemark = mission.getRemark();
                        String endWeatherInfo = String.format(" | 任务结束时的天气: 温度%.1f°C, 湿度%.1f%%",
                                endWeather.get("temperature"), endWeather.get("humidity"));
                        mission.setRemark(currentRemark + endWeatherInfo);
                    }

                    mission.setMissionReport(JSON.toJSONString(report));
                    droneMissionMapper.updateDroneMission(mission);
                }

                return report;
            } else {
                throw new RuntimeException(result.getString("message"));
            }
        } catch (Exception e) {
            throw new RuntimeException("停止任务失败: " + e.getMessage());
        }
    }

    @Override
    public Map<String, Object> getMissionStatus() {
        try {
            String url = droneServiceUrl + "/drone/mission/status";
            String response = HttpUtils.sendGet(url);
            JSONObject result = JSON.parseObject(response);

            if (result.getBooleanValue("success")) {
                Map<String, Object> statusData = result.getObject("data", Map.class);

                // 获取当前任务的位置信息
                String missionId = (String) statusData.get("mission_id");
                if (missionId != null) {
                    DroneMission mission = droneMissionMapper.selectDroneMissionById(missionId);
                    if (mission != null && mission.getFieldLocation() != null) {
                        // 添加实时天气信息到状态中
                        Map<String, Object> weatherInfo = satelliteWeatherService.getRealTimeWeather(mission.getFieldLocation());
                        statusData.put("current_weather", weatherInfo);

                        // 检查是否需要发出天气警告
                        String weatherWarning = checkWeatherWarning(weatherInfo);
                        if (weatherWarning != null) {
                            statusData.put("weather_warning", weatherWarning);
                        }
                    }
                }

                return statusData;
            } else {
                throw new RuntimeException(result.getString("message"));
            }
        } catch (Exception e) {
            throw new RuntimeException("获取任务状态失败: " + e.getMessage());
        }
    }

    @Override
    public Map<String, Object> getDroneStatus() {
        try {
            String url = droneServiceUrl + "/drone/status";
            String response = HttpUtils.sendGet(url);
            JSONObject result = JSON.parseObject(response);

            if (result.getBooleanValue("success")) {
                Map<String, Object> statusData = result.getObject("data", Map.class);

                // 添加默认位置的天气信息
                Map<String, Object> weatherInfo = satelliteWeatherService.getRealTimeWeather("默认农田区域");
                statusData.put("weather_info", weatherInfo);

                return statusData;
            } else {
                throw new RuntimeException(result.getString("message"));
            }
        } catch (Exception e) {
            throw new RuntimeException("获取无人机状态失败: " + e.getMessage());
        }
    }

    @Override
    public Map<String, Object> getMissionReport(String missionId) {
        try {
            DroneMission mission = droneMissionMapper.selectDroneMissionById(missionId);
            if (mission == null) {
                throw new RuntimeException("任务不存在");
            }

            Map<String, Object> report = new HashMap<String, Object>();
            report.put("mission_id", mission.getMissionId());
            report.put("mission_name", mission.getMissionName());
            report.put("start_time", mission.getStartTime());
            report.put("end_time", mission.getEndTime());
            report.put("field_area", mission.getFieldArea());
            report.put("flight_height", mission.getFlightHeight());
            report.put("monitoring_density", mission.getMonitoringDensity());
            report.put("status", mission.getStatus());
            report.put("detection_count", mission.getDetectionCount());
            report.put("main_pest", mission.getMainPest());
            report.put("field_location", mission.getFieldLocation());
            report.put("remark", mission.getRemark());

            // 添加天气信息
            if (mission.getFieldLocation() != null) {
                // 获取当前天气状况（用于对比）
                Map<String, Object> currentWeather = satelliteWeatherService.getRealTimeWeather(mission.getFieldLocation());
                report.put("current_weather_conditions", currentWeather);

                // 获取气象统计数据
                Map<String, Object> weatherStats = satelliteWeatherService.getWeatherStats(mission.getFieldLocation());
                report.put("weather_statistics", weatherStats);

                // 获取灾害预警信息
                List<Map<String, Object>> disasterAlerts = satelliteWeatherService.getDisasterAlerts();
                report.put("disaster_alerts", disasterAlerts);
            }

            // 如果有详细报告，解析JSON
            if (StringUtils.isNotEmpty(mission.getMissionReport())) {
                Map<String, Object> detailReport = JSON.parseObject(mission.getMissionReport(), Map.class);
                report.putAll(detailReport);
            }

            return report;
        } catch (Exception e) {
            throw new RuntimeException("获取任务报告失败: " + e.getMessage());
        }
    }

    @Override
    public DroneMission selectDroneMissionById(String missionId) {
        return droneMissionMapper.selectDroneMissionById(missionId);
    }

    @Override
    public List<DroneMission> selectDroneMissionList(DroneMission droneMission) {
        return droneMissionMapper.selectDroneMissionList(droneMission);
    }

    @Override
    public int insertDroneMission(DroneMission droneMission) {
        droneMission.setCreateTime(DateUtils.getNowDate());
        return droneMissionMapper.insertDroneMission(droneMission);
    }

    @Override
    public int updateDroneMission(DroneMission droneMission) {
        droneMission.setUpdateTime(DateUtils.getNowDate());
        return droneMissionMapper.updateDroneMission(droneMission);
    }

    @Override
    public int deleteDroneMissionById(String missionId) {
        return droneMissionMapper.deleteDroneMissionById(missionId);
    }

    @Override
    public int deleteDroneMissionByIds(String[] missionIds) {
        return droneMissionMapper.deleteDroneMissionByIds(missionIds);
    }

    /**
     * 检查天气警告
     */
    private String checkWeatherWarning(Map<String, Object> weatherInfo) {
        Double windSpeed = (Double) weatherInfo.get("windSpeed");
        Double rainfall = (Double) weatherInfo.get("rainfall");
        String disasterRisk = (String) weatherInfo.get("disasterRisk");

        StringBuilder warning = new StringBuilder();

        if (windSpeed != null && windSpeed > 8) {
            warning.append("风速较大(").append(windSpeed).append("m/s)，请注意飞行安全。");
        }

        if (rainfall != null && rainfall > 10) {
            if (warning.length() > 0) warning.append(" ");
            warning.append("有降雨(").append(rainfall).append("mm)，可能影响图像质量。");
        }

        if ("中风险".equals(disasterRisk)) {
            if (warning.length() > 0) warning.append(" ");
            warning.append("当前区域存在中度灾害风险，建议密切关注天气变化。");
        } else if ("高风险".equals(disasterRisk)) {
            if (warning.length() > 0) warning.append(" ");
            warning.append("当前区域存在高度灾害风险，建议暂停飞行任务。");
        }

        return warning.length() > 0 ? warning.toString() : null;
    }

    /**
     * 获取飞行适宜性评估
     */
    public Map<String, Object> getFlightSuitability(String location) {
        Map<String, Object> result = new HashMap<String, Object>();

        try {
            Map<String, Object> weatherData = satelliteWeatherService.getRealTimeWeather(location);

            // 评估飞行适宜性
            boolean suitable = true;
            List<String> reasons = new ArrayList<String>();

            Double windSpeed = (Double) weatherData.get("windSpeed");
            if (windSpeed > 10) {
                suitable = false;
                reasons.add("风速过大(" + windSpeed + "m/s)");
            }

            Double rainfall = (Double) weatherData.get("rainfall");
            if (rainfall > 15) {
                suitable = false;
                reasons.add("降雨量过大(" + rainfall + "mm)");
            }

            String disasterRisk = (String) weatherData.get("disasterRisk");
            if ("高风险".equals(disasterRisk)) {
                suitable = false;
                reasons.add("存在高风险自然灾害");
            }

            Double temperature = (Double) weatherData.get("temperature");
            if (temperature < 0 || temperature > 40) {
                reasons.add("温度极端(" + temperature + "°C)");
            }

            result.put("suitable", suitable);
            result.put("reasons", reasons);
            result.put("weather_data", weatherData);
            result.put("assessment_time", new Date());

        } catch (Exception e) {
            result.put("suitable", false);
            List<String> errorReasons = new ArrayList<String>();
            errorReasons.add("无法获取天气数据: " + e.getMessage());
            result.put("reasons", errorReasons);
        }

        return result;
    }

    /**
     * 获取综合环境报告
     */
    public Map<String, Object> getEnvironmentalReport(String missionId) {
        Map<String, Object> report = new HashMap<String, Object>();

        try {
            DroneMission mission = droneMissionMapper.selectDroneMissionById(missionId);
            if (mission == null) {
                throw new RuntimeException("任务不存在");
            }

            String location = mission.getFieldLocation();
            if (location == null) {
                location = "默认农田区域";
            }

            // 获取天气数据
            Map<String, Object> currentWeather = satelliteWeatherService.getRealTimeWeather(location);
            Map<String, Object> weatherStats = satelliteWeatherService.getWeatherStats(location);
            List<Map<String, Object>> disasterAlerts = satelliteWeatherService.getDisasterAlerts();

            // 构建环境报告
            Map<String, Object> missionInfo = new HashMap<String, Object>();
            missionInfo.put("mission_id", mission.getMissionId());
            missionInfo.put("mission_name", mission.getMissionName());
            missionInfo.put("location", location);

            Map<String, Object> taskPeriod = new HashMap<String, Object>();
            taskPeriod.put("start", mission.getStartTime());
            taskPeriod.put("end", mission.getEndTime());
            missionInfo.put("task_period", taskPeriod);

            report.put("mission_info", missionInfo);
            report.put("current_environment", currentWeather);
            report.put("historical_stats", weatherStats);
            report.put("risk_assessment", analyzeEnvironmentalRisks(currentWeather, disasterAlerts));
            report.put("recommendations", generateEnvironmentalRecommendations(currentWeather, weatherStats));
            report.put("alerts", disasterAlerts);

        } catch (Exception e) {
            throw new RuntimeException("生成环境报告失败: " + e.getMessage());
        }

        return report;
    }

    /**
     * 分析环境风险
     */
    private Map<String, Object> analyzeEnvironmentalRisks(Map<String, Object> weather, List<Map<String, Object>> alerts) {
        Map<String, Object> risks = new HashMap<String, Object>();
        int riskLevel = 0;
        List<String> riskFactors = new ArrayList<String>();

        // 分析天气风险
        Double windSpeed = (Double) weather.get("windSpeed");
        if (windSpeed > 8) {
            riskLevel = Math.max(riskLevel, 1);
            riskFactors.add("大风");
        }

        Double rainfall = (Double) weather.get("rainfall");
        if (rainfall > 10) {
            riskLevel = Math.max(riskLevel, 2);
            riskFactors.add("降雨");
        }

        String disasterRisk = (String) weather.get("disasterRisk");
        if ("中风险".equals(disasterRisk)) {
            riskLevel = Math.max(riskLevel, 2);
            riskFactors.add("中度灾害风险");
        } else if ("高风险".equals(disasterRisk)) {
            riskLevel = Math.max(riskLevel, 3);
            riskFactors.add("高度灾害风险");
        }

        // 分析预警风险
        if (alerts != null) {
            for (Map<String, Object> alert : alerts) {
                String level = (String) alert.get("level");
                if ("高风险".equals(level)) {
                    riskLevel = Math.max(riskLevel, 3);
                    riskFactors.add("灾害预警: " + alert.get("type"));
                }
            }
        }

        risks.put("risk_level", riskLevel);
        risks.put("risk_level_text", getRiskLevelText(riskLevel));
        risks.put("risk_factors", riskFactors);
        risks.put("overall_assessment", getRiskAssessment(riskLevel));

        return risks;
    }

    /**
     * 生成环境建议
     */
    private List<String> generateEnvironmentalRecommendations(Map<String, Object> weather, Map<String, Object> stats) {
        List<String> recommendations = new ArrayList<String>();

        Double windSpeed = (Double) weather.get("windSpeed");
        if (windSpeed != null && windSpeed > 6) {
            recommendations.add("当前风速较大，建议调整飞行高度或选择避风飞行路径");
        }

        Double rainfall = (Double) weather.get("rainfall");
        if (rainfall != null && rainfall > 5) {
            recommendations.add("有降雨情况，建议检查摄像头防护，确保图像采集质量");
        }

        Integer uvIndex = (Integer) weather.get("uvIndex");
        if (uvIndex != null && uvIndex > 7) {
            recommendations.add("紫外线强度高，建议在早晚时段进行飞行任务");
        }

        Double soilMoisture = (Double) weather.get("soilMoisture");
        if (soilMoisture != null && soilMoisture < 30) {
            recommendations.add("土壤湿度较低，可能与病虫害发生相关，建议重点关注");
        }

        // 基于统计数据的建议
        if (stats != null) {
            Integer disasterCount = (Integer) stats.get("disasterCount");
            if (disasterCount != null && disasterCount > 0) {
                recommendations.add("近期有灾害记录，建议加强监测频率");
            }
        }

        return recommendations;
    }

    private String getRiskLevelText(int riskLevel) {
        switch (riskLevel) {
            case 0: return "低风险";
            case 1: return "注意";
            case 2: return "中等风险";
            case 3: return "高风险";
            default: return "未知";
        }
    }

    private String getRiskAssessment(int riskLevel) {
        switch (riskLevel) {
            case 0: return "环境条件良好，适合飞行任务";
            case 1: return "环境条件基本适合，需注意个别因素";
            case 2: return "环境条件一般，建议谨慎飞行";
            case 3: return "环境条件较差，不建议飞行";
            default: return "无法评估";
        }
    }
}